<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      padding-left: 200px;
    }

    input, button {
      outline: none;
    }

    ul, li {
      list-style: none;
    }

    .addSale, .calc {
      width: 200px;
      height: 33px;
      background-color: skyblue;
      color: #fff;
      cursor: pointer;
      border: none;
      margin: 30px;
    }

    input {
      width: 300px;
      height: 30px;
      padding-left: 20px;
      font-size: 22px;
      display: block;
      margin: 20px;
    }

    ul {
      display: flex;
      margin: 20px;
    }

    ul > li {
      width: 120px;
      height: 120px;
      background-color: orange;
      margin: 10px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
      font-size: 30px;
      cursor: pointer;
    }

    ul > li.active {
      background-color: skyblue;
    }

    p {
      font-size: 100px;
      color: red;
      margin: 20px;
    }

  </style>
</head>
<body>

  <button class="addSale">添加折扣类型</button>

  <!-- 总价格 -->

  总价：<input type="text">


  <!-- 折扣类型 -->
  <ul>
    <li class="active">1111</li>
    <li>1111</li>
    <li>1111</li>
  </ul>

  <button class="calc">计算总价</button>

  <!-- 最终价格 -->
  最终价格：<p>0.00</p>


  折扣名称(显示在按钮上的文本): <input type="text" class="type">
  计算方式(总价以 x 表示): <input type="text" class="method">

  <script>
    /*
      收银台
    */

    // 0. 获取元素
    const ulBox = document.querySelector('ul')
    const calcBtn = document.querySelector('.calc')
    const totalInp = document.querySelector('input')
    const pBox = document.querySelector('p')

    const addBtn = document.querySelector('.addSale')
    const nameInp = document.querySelector('.type')
    const methodInp = document.querySelector('.method')

    // 0. 以策略模式的形式准备一个 折扣记录
    const calcPrice = (function () {

      // 折扣列表
      const calcList = {
        '80%': function (total) { return (total * 0.8).toFixed(2) },
        '300-30': function (total) { return total-Math.floor(total/300)*30 },
        '70%': function (total) { return (total * 0.7).toFixed(2) }
      }

      function inner(total, type) {
        if (!calcList[type]) return '0.00'

        return calcList[type](total)
      }

      // 往折扣列表中添加键值对
      inner.add = function (type, fn) {
        calcList[type] = fn
      }
      // 从折扣列表中 删除键值对
      inner.remove = function (type) {
        delete calcList[type]
      }
      // 获取整个折扣列表
      inner.getList = function () {
        return calcList
      }

      return inner
    })()

    // 0. 准备变量
    let type = ''

    // 1. 拿到当前所有的折扣渲染 li
    // 将来一旦折扣添加了, 需要重新渲染 li
    bindHtml()
    function bindHtml() {
      // 1-1. 拿到折扣类型列表
      const list = calcPrice.getList()

      // 1-2. 利用 list 渲染 li
      let str = ''
      for (let k in list) {
        str += `
          <li data-type="${ k }">${ k }</li>
        `
      }

      ulBox.innerHTML = str
    }


    // 2. 折扣类型的选择(排他)
    tab()
    function tab() {
      ulBox.addEventListener('click', e => {
        if (e.target.nodeName !== 'LI') return

        // 所有的没有类名
        for (let i = 0; i < ulBox.children.length; i++) {
          ulBox.children[i].classList.remove('active')
        }

        // 当前这个有类名
        e.target.classList.add('active')

        // 记录下当前的折扣类型
        type = e.target.dataset.type
      })
    }

    // 3. 结算按钮的事件
    calcBtn.addEventListener('click', () => {
      // 3-1. 拿到总价
      const totalPrice = totalInp.value - 0

      // 3-2. 计算最终价格
      const resultPrice = calcPrice(totalPrice, type)

      // 3-3. 把最终价渲染
      pBox.innerText = resultPrice
    })

    // 4. 添加折扣
    // 我们只能期望用户给我们两个内容
    //   折扣名称
    //   计算方式
    addBtn.addEventListener('click', () => {

      // 4-1. 拿到折扣名称
      const name = nameInp.value

      // 4-2. 拿到公式
      // 开始组装
      const r = '(parseInt(' + methodInp.value + ')).toFixed(2)'

      // 语法: eval(字符串)
      // 作用: 把该字符串当做js代码来执行
      // const res = eval(r)

      // 开始添加了
      calcPrice.add(name, x => eval(r))

      // 4-3. 从新渲染一遍 li
      bindHtml()

      // 4-4. 把两个文本框清空
      nameInp.value = ''
      methodInp.value = ''
    })
  </script>
</body>
</html>
